import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:jiffy/jiffy.dart';
import 'package:safetymonitor/app/core/core.dart';

import '../dialog/exit_tips.dart';

///基础版（固定时间，禁用时间，循环，自定义时间格式和回显） 通用高仿（ios或Android）时间滚轮选择器
//在页面中调用
//        MultiWheelTimePicker.show(
//         context: context,
//         onConfirm: (selectedDate) {
//           controller.initialDate=selectedDate;
//           print("选中的时间: $selectedDate");
//         },
//         visibleUnits: ['year', 'month', 'day', 'hour', 'minute', 'second'], // 显示年、月、日、时、分、秒
//         initialDate:controller.initialDate,//初始化时间
//         minYear: 2000,
//         maxYear: 2030,
//         // fixedDate: DateTime.now(), // 固定时间为 null，允许滚动
//         isLooping: false, // 启用循环滚动
//         // disabledDate: DateTime(2025, 1, 3),// 禁用的日期限制
//       );
class MultiWheelTimePicker extends StatefulWidget {
  const MultiWheelTimePicker({
    required this.onConfirm,
    super.key,
    this.initialDate,
    this.visibleUnits = const ['year', 'month', 'day', 'hour', 'minute', 'second'],
    this.minYear = 1900,
    this.maxYear = 2100,
    this.fixedDate,
    this.disabledDate,
    this.isLooping = false,
    this.pattern = 'yyyy-MM-dd HH:mm:ss',
  });

  ///初始化时间  例子: 2020-01-01 00:00:00 / 2020-01-01
  final String? initialDate;

  /// 显示年、月、日、时、分
  final List<String> visibleUnits;

  /// 最小年份
  final int minYear;

  /// 最大年份
  final int maxYear;

  /// 固定时间为 null，允许滚动
  final DateTime? fixedDate;

  /// 禁用的日期限制
  final DateTime? disabledDate;

  /// 启用循环滚动
  final bool isLooping;

  ///  用户选择后触发的回调
  final void Function(String) onConfirm;
  final String pattern;

  ///当你需要在某个界面使用 MultiWheelTimePicker 时，可以通过 show 静态方法调用
  static void show({
    required void Function(String) onConfirm,
    BuildContext? context,
    String? initialDate,
    List<String> visibleUnits = const ['year', 'month', 'day', 'hour', 'minute', 'second'],
    int minYear = 1900,
    int maxYear = 2100,
    DateTime? fixedDate,
    DateTime? disabledDate,
    bool isLooping = false,
    String pattern = 'yyyy-MM-dd HH:mm:ss',
  }) {
    showModalBottomSheet(
      context: context ?? Get.context!,
      builder: (_) => MultiWheelTimePicker(
        onConfirm: onConfirm,
        initialDate: initialDate,
        visibleUnits: visibleUnits,
        minYear: minYear,
        maxYear: maxYear,
        fixedDate: fixedDate,
        disabledDate: disabledDate,
        isLooping: isLooping,
        pattern: pattern,
      ),
    );
  }

  @override
  _MultiWheelTimePickerState createState() => _MultiWheelTimePickerState();
}

class _MultiWheelTimePickerState extends State<MultiWheelTimePicker> {
  late int selectedYear;
  late int selectedMonth;
  late int selectedDay;
  late int selectedHour;
  late int selectedMinute;
  late int selectedSecond;

  @override
  void initState() {
    super.initState();
    if (widget.fixedDate != null) {
      selectedYear = widget.fixedDate!.year;
      selectedMonth = widget.fixedDate!.month;
      selectedDay = widget.fixedDate!.day;
      selectedHour = widget.fixedDate!.hour;
      selectedMinute = widget.fixedDate!.minute;
      selectedSecond = widget.fixedDate!.second;
    } else {
      //下面的主要用途是区分是否disabledDate启用后  为pattern的格式设置默认值而不是当前时间
      _initializeSelectedDate();
    }
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Container(
        color: Colors.white,
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            _buildHeader(),
            SizedBox(
              height: 250.w,
              child: Row(
                children: widget.visibleUnits.map((unit) => Expanded(child: _buildPicker(unit))).toList(),
              ),
            ),
          ],
        ),
      ),
    );
  }

  ///功能：检查用户选择的时间是否合法。
// 逻辑：
// 创建一个 DateTime 实例 selectedDateTime，保存用户当前的选择。
// 检查 disabledDate 是否设置，以及 selectedDateTime 是否晚于 disabledDate。
// 如果非法，弹出提示框，提示用户选择合法时间。
// 如果合法，调用回调函数并关闭弹框。
  Widget _buildHeader() {
    return Container(
      color: Colors.grey[200],
      padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 8.w),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          TextButton(
            onPressed: () => Navigator.of(context).pop(),
            child: Text('取消', style: TextStyle(fontSize: 16.sp)),
          ),
          Text('时间选择器', style: TextStyle(fontSize: 18.sp)),
          // 头部的“确定”按钮逻辑
          TextButton(
            onPressed: () {
              final DateTime selectedDateTime = DateTime(
                selectedYear,
                selectedMonth,
                selectedDay,
                selectedHour,
                selectedMinute,
                selectedSecond,
              );

              // 检查当前选择的时间是否超过禁用时间
              if (widget.disabledDate != null && selectedDateTime.isAfter(widget.disabledDate!)) {
                Get.dialog<bool>(ExitTips(
                  content: '当前选择的时间不可用，请选择更早的时间。',
                  func: (v) {
                    if (v) {}
                  },
                ));
                return; // 阻止关闭弹框
              }
              // 如果时间合法，触发回调并关闭弹框
              widget.onConfirm(Jiffy.parseFromDateTime(selectedDateTime).format(pattern: widget.pattern));
              Navigator.of(context).pop();
            },
            child: Text('确定', style: TextStyle(fontSize: 16.sp)),
          ),
        ],
      ),
    );
  }

  Widget _buildPicker(String unit) {
    if (widget.fixedDate != null) {
      return Center(
        child: Text(
          _formatFixedValue(unit),
          style: TextStyle(fontSize: 16.sp),
        ),
      );
    }

    int itemCount;
    FixedExtentScrollController controller;
    // itemBuilder下:比较年、月、日、时、分、秒，确保每个单位的滚动项正确禁用。如果某一项的值大于禁用日期的对应值，则该项被禁用并显示为灰色
    switch (unit) {
      case 'year':
        itemCount = widget.maxYear - widget.minYear + 1;
        controller = FixedExtentScrollController(
          //为项目大小相同的滚动条创建滚动控制器。
          initialItem: selectedYear - widget.minYear,
        );
        return _buildCupertinoPicker(
          itemCount: itemCount,
          controller: controller,
          isLooping: widget.isLooping,
          unit: unit,
          onSelectedItemChanged: (index) {
            setState(() {
              selectedYear = widget.minYear + index; // 更新选中年份
            });
          },
          itemBuilder: (index) {
            final int year = widget.minYear + index;
            final bool isDisabled = widget.disabledDate != null && year > widget.disabledDate!.year;
            return _buildPickerItem('$year年', isDisabled); // 显示年
          },
        );
      case 'month':
        itemCount = 12;
        controller = FixedExtentScrollController(
          initialItem: selectedMonth - 1,
        );
        return _buildCupertinoPicker(
          itemCount: itemCount,
          controller: controller,
          isLooping: widget.isLooping,
          unit: unit,
          onSelectedItemChanged: (index) {
            setState(() {
              selectedMonth = index + 1;
            });
          },
          itemBuilder: (index) {
            final int month = index + 1;
            final bool isDisabled = widget.disabledDate != null &&
                (selectedYear > widget.disabledDate!.year || (selectedYear == widget.disabledDate!.year && month > widget.disabledDate!.month));
            return _buildPickerItem('$month月', isDisabled);
          },
        );
      case 'day':
        itemCount = _getDaysInMonth(selectedYear, selectedMonth);
        controller = FixedExtentScrollController(
          initialItem: selectedDay - 1,
        );
        return _buildCupertinoPicker(
          itemCount: itemCount,
          controller: controller,
          isLooping: widget.isLooping,
          unit: unit,
          onSelectedItemChanged: (index) {
            setState(() {
              selectedDay = index + 1;
            });
          },
          itemBuilder: (index) {
            final int day = index + 1;
            final bool isDisabled = widget.disabledDate != null &&
                (selectedYear > widget.disabledDate!.year ||
                    (selectedYear == widget.disabledDate!.year && selectedMonth > widget.disabledDate!.month) ||
                    (selectedYear == widget.disabledDate!.year && selectedMonth == widget.disabledDate!.month && day > widget.disabledDate!.day));
            return _buildPickerItem('$day日', isDisabled);

          },
        );
      case 'hour':
        itemCount = 24;
        controller = FixedExtentScrollController(
          initialItem: selectedHour,
        );
        return _buildCupertinoPicker(
          itemCount: itemCount,
          controller: controller,
          isLooping: widget.isLooping,
          unit: unit,
          onSelectedItemChanged: (index) {
            setState(() {
              selectedHour = index;
            });
          },
          itemBuilder: (index) {
            final bool isDisabled = widget.disabledDate != null &&
                (selectedYear > widget.disabledDate!.year ||
                    (selectedYear == widget.disabledDate!.year && selectedMonth > widget.disabledDate!.month) ||
                    (selectedYear == widget.disabledDate!.year && selectedMonth == widget.disabledDate!.month && selectedDay > widget.disabledDate!.day) ||
                    (selectedYear == widget.disabledDate!.year && selectedMonth == widget.disabledDate!.month && selectedDay == widget.disabledDate!.day && index > widget.disabledDate!.hour));
            return _buildPickerItem('$index时', isDisabled);

          },
        );
      case 'minute':
        itemCount = 60;
        controller = FixedExtentScrollController(
          initialItem: selectedMinute,
        );
        return _buildCupertinoPicker(
          itemCount: itemCount,
          controller: controller,
          isLooping: widget.isLooping,
          unit: unit,
          onSelectedItemChanged: (index) {
            setState(() {
              selectedMinute = index;
            });
          },
          itemBuilder: (index) {
            final bool isDisabled = widget.disabledDate != null &&
                (selectedYear > widget.disabledDate!.year ||
                    (selectedYear == widget.disabledDate!.year && selectedMonth > widget.disabledDate!.month) ||
                    (selectedYear == widget.disabledDate!.year && selectedMonth == widget.disabledDate!.month && selectedDay > widget.disabledDate!.day) ||
                    (selectedYear == widget.disabledDate!.year && selectedMonth == widget.disabledDate!.month && selectedDay == widget.disabledDate!.day && selectedHour > widget.disabledDate!.hour) ||
                    (selectedYear == widget.disabledDate!.year && selectedMonth == widget.disabledDate!.month && selectedDay == widget.disabledDate!.day && selectedHour == widget.disabledDate!.hour && index > widget.disabledDate!.minute));
            return _buildPickerItem('$index分', isDisabled);

          },
        );
      case 'second':
        itemCount = 60;
        controller = FixedExtentScrollController(
          initialItem: selectedSecond,
        );
        return _buildCupertinoPicker(
          itemCount: itemCount,
          controller: controller,
          isLooping: widget.isLooping,
          unit: unit,
          onSelectedItemChanged: (index) {
            setState(() {
              selectedSecond = index;
            });
          },
          itemBuilder: (index) {
            final bool isDisabled = widget.disabledDate != null &&
                (selectedYear > widget.disabledDate!.year ||
                    (selectedYear == widget.disabledDate!.year && selectedMonth > widget.disabledDate!.month) ||
                    (selectedYear == widget.disabledDate!.year && selectedMonth == widget.disabledDate!.month && selectedDay > widget.disabledDate!.day) ||
                    (selectedYear == widget.disabledDate!.year && selectedMonth == widget.disabledDate!.month && selectedDay == widget.disabledDate!.day && selectedHour > widget.disabledDate!.hour) ||
                    (selectedYear == widget.disabledDate!.year && selectedMonth == widget.disabledDate!.month && selectedDay == widget.disabledDate!.day && selectedHour == widget.disabledDate!.hour && selectedMinute > widget.disabledDate!.minute) ||
                    (selectedYear == widget.disabledDate!.year && selectedMonth == widget.disabledDate!.month && selectedDay == widget.disabledDate!.day && selectedHour == widget.disabledDate!.hour && selectedMinute == widget.disabledDate!.minute && index > widget.disabledDate!.second));
            return _buildPickerItem('$index秒', isDisabled);
          },
        );
      default:
        return Container();
    }
  }

  // 自定义的滚轮选择项显示
  //关键点：
  // 判断是否禁用，禁用的项显示为灰色，正常项显示为黑色。
  // 使用 Text 小部件渲染文字内容。
  Widget _buildPickerItem(String text, bool isDisabled) {
    return Text(
      text,
      style: TextStyle(
        fontSize: 16.sp,
        color: isDisabled ? Colors.grey : Colors.black, // 禁用项显示为灰色
      ),
    );
  }

  ///功能：通用的滚轮选择器。
  // 关键点：
  // itemExtent：设置每个滚轮项的高度。
  // scrollController：用于控制滚动。
  // isLooping：决定是否循环滚动。
  // itemBuilder：动态构建滚轮每一项。
  Widget _buildCupertinoPicker({
    required int itemCount,
    required FixedExtentScrollController controller,
    required bool isLooping,
    required String unit,
    required void Function(int) onSelectedItemChanged,
    required Widget Function(int) itemBuilder,
  }) {
    //CupertinoPicker是Flutter框架中用于实现iOS风格的选择器的组件
    //iOS风格选择器：提供类似iPhone上的滚轮选择器，用户可以通过滚动来选择选项。
    // 自定义子组件：可以包含任意数量的子组件（如文本、图标等），这些子组件会以滚轮形式展示。
    // 响应选择变化：通过onSelectedItemChanged回调函数，可以在用户选择不同项时执行相应操作。
    // 固定高度：默认情况下，CupertinoPicker的高度是固定的，通常为216逻辑像素
    return CupertinoPicker.builder(
      itemExtent: 40,
      // 每项的高度
      scrollController: controller,
      // 控制滚动行为
      onSelectedItemChanged: onSelectedItemChanged,
      // 滚动改变时回调
      childCount: isLooping ? null : itemCount,
      // 如果循环滚动，childCount 设为 null
      itemBuilder: (context, index) {
        if (isLooping) index = index % itemCount; // 循环滚动时，计算实际索引
        return Center(child: itemBuilder(index)); // 构建单项内容
      },
    );
  }

  ///功能：计算指定年份和月份的天数。
  // 逻辑：
  // 利用 Dart 的 DateTime 构造函数，传入下一月的第 0 天，返回当前月的最后一天。
  int _getDaysInMonth(int year, int month) {
    if (month == 12) {
      return DateTime(year + 1, 1, 0).day; // 获取下一年的第0天，即当前年12月的最后一天
    } else {
      return DateTime(year, month + 1, 0).day; // 获取当前年下一个月的第0天，即本月的最后一天
    }
  }

  String _formatFixedValue(String unit) {
    switch (unit) {
      case 'year':
        return '${widget.fixedDate!.year}年';
      case 'month':
        return '${widget.fixedDate!.month}月';
      case 'day':
        return '${widget.fixedDate!.day}日';
      case 'hour':
        return '${widget.fixedDate!.hour}时';
      case 'minute':
        return '${widget.fixedDate!.minute}分';
      case 'second':
        return '${widget.fixedDate!.second}秒';
      default:
        return '';
    }
  }

  /// 获取有效的初始日期 和 处理禁用的日期限制
  void _initializeSelectedDate() {
    // 处理初始日期
    DateTime initialDateTime;

    if (widget.initialDate == null || widget.initialDate!.isEmpty) {
      initialDateTime = DateTime.now(); // 初始日期为空时使用当前时间
    } else {
      // 预处理 initialDate
      String formattedDate = widget.initialDate!;
      if (widget.pattern == 'yyyy' && !formattedDate.contains('-')) {
        formattedDate = '$formattedDate-01-01'; // 如果只有年份，补充默认的月和日
      } else if (widget.pattern == 'yyyy-MM' && formattedDate.split('-').length == 1) {
        formattedDate = '$formattedDate-01'; // 如果是 "yyyy-MM"，补充默认的日
      }

      // 尝试解析日期
      try {
        initialDateTime = DateTime.parse(formattedDate);
      } catch (e) {
        initialDateTime = DateTime.now(); // 解析失败时使用当前时间
      }
    }
    // 初始化选中的日期
    selectedYear = initialDateTime.year;
    selectedMonth = initialDateTime.month;
    selectedDay = initialDateTime.day;
    selectedHour = initialDateTime.hour;
    selectedMinute = initialDateTime.minute;
    selectedSecond = initialDateTime.second;
    // 根据 pattern 设置具体的默认值
    //-----------------------主要处理disabledDate启用后-------------------------------------
    // 如果是当前的时间 这里就需要考虑pattern 设置默认值
    switch (widget.pattern) {
      case 'yyyy':
        selectedMonth = 1;
        selectedDay = 1;
        selectedHour = 0;
        selectedMinute = 0;
        selectedSecond = 0;
        break;
      case 'yyyy-MM':
        selectedDay = 1;
        selectedHour = 0;
        selectedMinute = 0;
        selectedSecond = 0;
        break;
      case 'yyyy-MM-dd':
        selectedHour = 0;
        selectedMinute = 0;
        selectedSecond = 0;
        break;
      case 'yyyy-MM-dd HH':
        selectedMinute = 0;
        selectedSecond = 0;
        break;
      case 'yyyy-MM-dd HH:mm':
        selectedSecond = 0;
        break;
      default:
        break; // 默认已经是完整的日期时间格式
    }
  }
}
